package com.my.library.dao.impl;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Component;

import com.my.library.dao.AbstractDAO;
import com.my.library.entity.Role;
import com.my.library.entity.User;

@Component
public class UserDAO extends AbstractDAO<User> {

	public User getUserByName(String name) {
		String sql = "select u.id, u.name, u.password, u.university, r.id as roleId, r.name as roleName from user u left join user_role ur on u.id = ur.user_id left join role r on ur.role_id = r.id where u.name = ?";
		List<User> users = super.getJdbcTemplate().query(sql,
				new RowMapper<User>() {

					@Override
					public User mapRow(ResultSet rs, int arg1)
							throws SQLException {
						User u = new User();
						u.setId(rs.getInt("id"));
						u.setName(rs.getString("name"));
						u.setPassword(rs.getString("password"));
						u.setUniversity(rs.getString("university"));
						Role r = new Role();
						r.setId(rs.getInt("roleId"));
						r.setName(rs.getString("roleName"));
						u.getRoles().add(r);
						return u;
					}

				}, name);
		System.out.println("users: "+ users);
		if (users.isEmpty()) {
			return null;
		}
		return users.get(0);
	}

	public Map<String, List<String>> loadRoleAppAuth() {
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		StringBuilder sql = new StringBuilder(100);
		sql.append("SELECT a.url, r.name ");
		sql.append("FROM role r ");
		sql.append("INNER JOIN role_app_auth ra ON r.id = ra.role_id ");
		sql.append("INNER JOIN app a ON ra.app_id = a.id and (ra.visibility = 1 or ra.usability = 1)");
		SqlRowSet rs = super.getJdbcTemplate().queryForRowSet(sql.toString());
		while(rs.next()) {
			String url = rs.getString(1);
			String role = rs.getString(2);
			if(map.containsKey(url)) {
				map.get(url).add(role);
			} else {
				List<String> roles = new ArrayList<String>();
				roles.add(role);
				map.put(url, roles);
			}
		}
		return map;
	}

	public List<Map<String, Object>> getAppOfUser(int id) {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT a.id, a.name, a.url ");
		sql.append("FROM USER u, user_role ur, role r, role_app_auth ra, app a ");
		sql.append("WHERE u.id = ur.user_id AND ur.role_id = r.id ");
		sql.append("AND r.id = ra.role_id AND ra.app_id = a.id ");
		sql.append("AND u.id = ? AND a.pid = 0 and ra.visibility = 1");
		List<Map<String, Object>> ret = super.getJdbcTemplate().queryForList(sql.toString(), new Integer(id));
		return ret;
	}

	/*public String getData(Set<Role> rs, int appId) {
		return super.getData(rs, appId);
	}*/
	
	
	public static void main(String[] args) {
		User dao = new User();
		
		/*System.out.println(dao.getClass().getSimpleName());
		
		ParameterizedType p = (ParameterizedType) dao.getClass().getGenericSuperclass();
		System.out.println(p.getRawType());
		System.out.println(Arrays.toString(p.getActualTypeArguments()));
		System.out.println(p.getOwnerType());
		
		System.out.println(dao.createXML(null, null));*/
		
		System.out.println(dao.getClass().getSimpleName());
		
		try {
			System.out.println(dao.getClass().getConstructor().getName());
		} catch (SecurityException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (NoSuchMethodException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		for(Field f: dao.getClass().getDeclaredFields()) {
			f.setAccessible(true);
			System.out.println(f.getName());
			if(f.getName().equals("name")) {
				try {
					f.set(dao, "abc");
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		System.out.println(dao.getName());
	}
	
}
